
	//====================================================================================================//
	// Serial Port Programming using Win32 API in C                                                       //
	// (Reads data from serial port)                                                                      //
	//====================================================================================================//
	
	//====================================================================================================//
	// www.xanthium.in										                                              //
	// Copyright (C) 2014 Rahul.S                                                                         //
	//====================================================================================================//
	
	//====================================================================================================//
	// The Program runs on the PC side and uses Win32 API to communicate with the serial port or          //
	// USB2SERIAL board and reads the data from it.                                                       //       
	//----------------------------------------------------------------------------------------------------//
	// Program runs on the PC side (Windows) and receives a string of characters.                         //            
	// Program uses CreateFile() function to open a connection serial port(COMxx).                        //
	// Program then sets the parameters of Serial Comm like Baudrate,Parity,Stop bits in the DCB struct.  //
	// After setting the Time outs,the Program waits for the reception of string of characters by setting-//
	// -up the  WaitCommEvent().                                                                          //
	// When a character is reeived bythe PC UART WaitCommEvent() returns and the received string is read- //
	// -using ReadFile(); function.The characters are then displayed on the Console.                      //
	//----------------------------------------------------------------------------------------------------// 
	// BaudRate     -> 9600                                                                               //
	// Data formt   -> 8 databits,No parity,1 Stop bit (8N1)                                              //
	// Flow Control -> None                                                                               //
	//----------------------------------------------------------------------------------------------------//
	
	
	//====================================================================================================//
	// Compiler/IDE  :	Microsoft Visual Studio Express 2013 for Windows Desktop(Version 12.0)            //
	//               :  gcc 4.8.1 (MinGW)                                                                 //
	//                                                                                                    //
	// Library       :  Win32 API,windows.h,                                                              //
	// Commands      :  gcc -o USB2SERIAL_Read_W32 USB2SERIAL_Read_W32.c                                  //
	// OS            :	Windows(Windows 7)                                                                //
	// Programmer    :	Rahul.S                                                                           //
	// Date	         :	30-November-2014                                                                  //
	//====================================================================================================//

	//====================================================================================================//
	// Sellecting the COM port Number                                                                     //
	//----------------------------------------------------------------------------------------------------//
	// Use "Device Manager" in Windows to find out the COM Port number allotted to USB2SERIAL converter-  // 
	// -in your Computer and substitute in the  "ComPortName[]" array.                                    //
	//                                                                                                    //
	// for eg:-                                                                                           //
	// If your COM port number is COM32 in device manager(will change according to system)                //
	// then                                                                                               //
	//			char   ComPortName[] = "\\\\.\\COM32";                                                    //
	//====================================================================================================//

	#include <Windows.h>
	#include <stdio.h>
  #include "stdlib.h"

unsigned char ptz_cmd[][7]={
{0xFF,0x01,0x00,0x4D,0x00,0x00,0x4E},//发送命令1=(垂直0度):FF 01 00 4D 00 00 4E
{0xFF,0x01,0x00,0x4D,0x80,0xE8,0xB6},//发送命令2=(垂直30度):FF 01 00 4D 80 E8 B6
{0xFF,0x01,0x00,0x4D,0x75,0x30,0xF3},//发送命令3=(垂直60度):FF 01 00 4D 75 30 F3
{0xFF,0x01,0x00,0x4D,0x6D,0x60,0x1B},//发送命令4=(垂直80度):FF 01 00 4D 6D 60 1B
{0xFF,0x01,0x00,0x4D,0x69,0xDC,0x93},//发送命令5=(垂直90度):FF 01 00 4D 69 DC 93
{0xFF,0x01,0x00,0x4D,0x6D,0x60,0x1B},//发送命令6=(垂直80度):FF 01 00 4D 6D 60 1B
{0xFF,0x01,0x00,0x4D,0x75,0x30,0xF3},//发送命令7=(垂直60度):FF 01 00 4D 75 30 F3
{0xFF,0x01,0x00,0x4D,0x80,0xE8,0xB6},//发送命令8=(垂直30度):FF 01 00 4D 80 E8 B6
{0xFF,0x01,0x00,0x4D,0x00,0x00,0x4E},//发送命令9=(垂直0度):FF 01 00 4D 00 00 4E
{0xFF,0x01,0x00,0x4D,0x03,0xE8,0x39},//发送命令10=(垂直-10度):FF 01 00 4D 03 E8 39
{0xFF,0x01,0x00,0x4D,0x0F,0xA0,0xFD},//发送命令11=(垂直-40度):FF 01 00 4D 0F A0 FD
{0xFF,0x01,0x00,0x4D,0x13,0x88,0xE9},//发送命令12=(垂直-50度):FF 01 00 4D 13 88 E9
{0xFF,0x01,0x00,0x4D,0x17,0x70,0xD5},//发送命令13=(垂直-60度):FF 01 00 4D 17 70 D5
{0xFF,0x01,0x00,0x4D,0x1B,0x58,0xC1},//发送命令14=(垂直-70度):FF 01 00 4D 1B 58 C1
{0xFF,0x01,0x00,0x4D,0x1F,0x40,0xAD},//发送命令15=(垂直-80度):FF 01 00 4D 1F 40 AD
{0xFF,0x01,0x00,0x4D,0x22,0xC4,0x34},//发送命令16=(垂直-89度):FF 01 00 4D 22 C4 34
{0xFF,0x01,0x00,0x4D,0x1F,0x40,0xAD},//发送命令17=(垂直-80度):FF 01 00 4D 1F 40 AD
{0xFF,0x01,0x00,0x4D,0x1B,0x58,0xC1},//发送命令18=(垂直-70度):FF 01 00 4D 1B 58 C1
{0xFF,0x01,0x00,0x4D,0x17,0x70,0xD5},//发送命令19=(垂直-60度):FF 01 00 4D 17 70 D5
{0xFF,0x01,0x00,0x4D,0x13,0x88,0xE9},//发送命令20=(垂直-50度):FF 01 00 4D 13 88 E9
{0xFF,0x01,0x00,0x4D,0x0F,0xA0,0xFD},//发送命令21=(垂直-40度):FF 01 00 4D 0F A0 FD
{0xFF,0x01,0x00,0x4D,0x0B,0xB8,0x11},//发送命令22=(垂直-30度):FF 01 00 4D 0B B8 11
{0xFF,0x01,0x00,0x4D,0x07,0xD0,0x25},//发送命令23=(垂直-20度):FF 01 00 4D 07 D0 25
{0xFF,0x01,0x00,0x4D,0x03,0xE8,0x39},//发送命令24=(垂直-10度):FF 01 00 4D 03 E8 39
{0xFF,0x01,0x00,0x4D,0x00,0x00,0x4E},//发送命令24+=(垂直0度):FF 01 00 4D 00 00 4E
{0xFF,0x01,0x00,0x4B,0x00,0x00,0x4C},//发送命令25=(水平0度):FF 01 00 4B 00 00 4C
{0xFF,0x01,0x00,0x4B,0x0B,0xB8,0x0F},//发送命令26=(水平30度):FF 01 00 4B 0B B8 0F
{0xFF,0x01,0x00,0x4B,0x17,0x70,0xD3},//发送命令27=(水平60度):FF 01 00 4B 17 70 D3
{0xFF,0x01,0x00,0x4B,0x23,0x28,0x97},//发送命令28=(水平90度):FF 01 00 4B 23 28 97
{0xFF,0x01,0x00,0x4B,0x2E,0xE0,0x5A},//发送命令29=(水平120度):FF 01 00 4B 2E E0 5A
{0xFF,0x01,0x00,0x4B,0x3A,0x98,0x1E},//发送命令30=(水平150度):FF 01 00 4B 3A 98 1E
{0xFF,0x01,0x00,0x4B,0x46,0x50,0xE2},//发送命令31=(水平180度):FF 01 00 4B 46 50 E2
{0xFF,0x01,0x00,0x4B,0x52,0x08,0xA6},//发送命令32=(水平210度):FF 01 00 4B 52 08 A6
{0xFF,0x01,0x00,0x4B,0x5D,0xC0,0x69},//发送命令33=(水平240度):FF 01 00 4B 5D C0 69
{0xFF,0x01,0x00,0x4B,0x69,0x78,0x2D},//发送命令34=(水平270度):FF 01 00 4B 69 78 2D
{0xFF,0x01,0x00,0x4B,0x75,0x30,0xF1},//发送命令35=(水平300度):FF 01 00 4B 75 30 F1
{0xFF,0x01,0x00,0x4B,0x80,0xE8,0xB4},//发送命令36=(水平330度):FF 01 00 4B 80 E8 B4
{0xFF,0x01,0x00,0x4B,0x00,0x00,0x4C},//发送命令37=(水平0度):FF 01 00 4B 00 00 4C
{0xFF,0x01,0x00,0x4B,0x80,0xE8,0xB4},//发送命令38=(水平330度):FF 01 00 4B 80 E8 B4
{0xFF,0x01,0x00,0x4B,0x75,0x30,0xF1},//发送命令39=(水平300度):FF 01 00 4B 75 30 F1
{0xFF,0x01,0x00,0x4B,0x69,0x78,0x2D},//发送命令40=(水平270度):FF 01 00 4B 69 78 2D
{0xFF,0x01,0x00,0x4B,0x5D,0xC0,0x69},//发送命令41=(水平240度):FF 01 00 4B 5D C0 69
{0xFF,0x01,0x00,0x4B,0x52,0x08,0xA6},//发送命令42=(水平210度):FF 01 00 4B 52 08 A6
{0xFF,0x01,0x00,0x4B,0x46,0x50,0xE2},//发送命令43=(水平180度):FF 01 00 4B 46 50 E2
{0xFF,0x01,0x00,0x4B,0x3A,0x98,0x1E},//发送命令44=(水平150度):FF 01 00 4B 3A 98 1E
{0xFF,0x01,0x00,0x4B,0x2E,0xE0,0x5A},//发送命令45=(水平120度):FF 01 00 4B 2E E0 5A
{0xFF,0x01,0x00,0x4B,0x23,0x28,0x97},//发送命令46=(水平90度):FF 01 00 4B 23 28 97
{0xFF,0x01,0x00,0x4B,0x17,0x70,0xD3},//发送命令47=(水平60度):{0xFF 01 00 4B 17 70 D3
{0xFF,0x01,0x00,0x4B,0x0B,0xB8,0x0F},//发送命令48=(水平30度):FF 01 00 4B 0B B8 0F
{0xFF,0x01,0x00,0x4B,0x00,0x00,0x4C},//发送命令49=(水平0度):FF 01 00 4B 00 00 4C
};

  int com_rx(HANDLE hComm,unsigned char *rxbuf);
  int com_tx(HANDLE hComm,unsigned char *txbuf, unsigned char txlen);
  
  unsigned char check_sum(unsigned char * buf, unsigned char len)
  {
    unsigned char i,res=0;
    
    for(i=0;i<len;i++)
    {
      res += buf[i];
    }
    
    return res;
  }
  
void main(int argc,char *argv[])
{
	FILE *fp;
	HANDLE hComm;                          // Handle to the Serial port
	char  ComPortName[16];// = "\\\\.\\COM8";  // Name of the Serial port(May Change) to be opened,
	BOOL  Status;                          // Status of the various operations 
	DWORD dwEventMask;                     // Event mask to trigger
	char  TempChar;                        // Temperory Character
	unsigned char  SerialBuffer[16];               // Buffer Containing Rxed Data
	DWORD NoBytesRead;                     // Bytes read by ReadFile()
	int i = 0;
      int j =0;
      int res = -1;
      char txbuf[256];
      char fpath[256];
      unsigned int offset=0;
      int eof = 0;
      unsigned int size;

      if(argc != 3) 
      {
        res = -1;
        goto arg_err;
		 }

      printf("argv[0]:%s\n",argv[0]);
      printf("argv[1]:%s\n",argv[1]);
      printf("argv[2]:%s\n",argv[2]);

      if(strcmp(argv[1],"-s") == 0)
      {
        res = 0;
        sprintf(ComPortName,"\\\\.\\COM%d",atoi(argv[2]));
      }
      else
      {
        res = -1;
      }
      
      arg_err:
      if(res == -1)
      {
        printf("\narguments input error,%s -s 8",argv[0]);
        printf("\nexit!\n");
        //_getch();
        return;
      }


      res = -1;
     
			/*---------------------------------- Opening the Serial Port -------------------------------------------*/
			
			hComm = CreateFile( ComPortName,                  // Name of the Port to be Opened
		                        GENERIC_READ | GENERIC_WRITE, // Read/Write Access
								0,                            // No Sharing, ports cant be shared
								NULL,                         // No Security
							    OPEN_EXISTING,                // Open existing port only
		                        0,                            // Non Overlapped I/O
		                        NULL);                        // Null for Comm Devices

			if (hComm == INVALID_HANDLE_VALUE) 
      {   
				printf("\n    Error! - Port %s can't be opened\n", ComPortName);
        goto end;
      }
			else
				printf("\n    Port %s Opened\n ", ComPortName);

			/*------------------------------- Setting the Parameters for the SerialPort ------------------------------*/
			
			DCB dcbSerialParams = { 0 };                         // Initializing DCB structure
			dcbSerialParams.DCBlength = sizeof(dcbSerialParams);

			Status = GetCommState(hComm, &dcbSerialParams);      //retreives  the current settings

			if (Status == FALSE)
				printf("\n    Error! in GetCommState()");

			dcbSerialParams.BaudRate = CBR_9600;      // Setting BaudRate = 9600
			dcbSerialParams.ByteSize = 8;             // Setting ByteSize = 8
			dcbSerialParams.StopBits = ONESTOPBIT;    // Setting StopBits = 1
			dcbSerialParams.Parity = NOPARITY;        // Setting Parity = None 

			Status = SetCommState(hComm, &dcbSerialParams);  //Configuring the port according to settings in DCB 

			if (Status == FALSE)
				{
					printf("\n    Error! in Setting DCB Structure");
				}
			else //If Successfull display the contents of the DCB Structure
				{
					printf("\n\n    Setting DCB Structure Successfull\n");
					printf("\n       Baudrate = %d", dcbSerialParams.BaudRate);
					printf("\n       ByteSize = %d", dcbSerialParams.ByteSize);
					printf("\n       StopBits = %d", dcbSerialParams.StopBits);
					printf("\n       Parity   = %d", dcbSerialParams.Parity);
				}

			/*------------------------------------ Setting Timeouts --------------------------------------------------*/
			
			COMMTIMEOUTS timeouts = { 50 };
			timeouts.ReadIntervalTimeout         = 5;
			timeouts.ReadTotalTimeoutConstant    = 150;
			timeouts.ReadTotalTimeoutMultiplier  = 5;
			timeouts.WriteTotalTimeoutConstant   = 50;
			timeouts.WriteTotalTimeoutMultiplier = 5;
			
			if (SetCommTimeouts(hComm, &timeouts) == FALSE)
				printf("\n\n    Error! in Setting Time Outs");
			else
				printf("\n\n    Setting Serial Port Timeouts Successfull");

			/*------------------------------------ Setting Receive Mask ----------------------------------------------*/
			
			Status = SetCommMask(hComm, EV_RXCHAR); //Configure Windows to Monitor the serial device for Character Reception
	
			if (Status == FALSE)
				printf("\n\n    Error! in Setting CommMask");
			else
				printf("\n\n    Setting CommMask successfull");


 printf("\nptz control test start\n");
 printf("total cmd:%d\n",sizeof(ptz_cmd)/7);
      int index = 0;
	  int cnt = 0;
      do{
		printf("control cnt:%d\n",cnt++);
		if (com_tx(hComm,ptz_cmd[index],7) != 0)
        {  
			printf("\n\n   Error %d in Writing to Serial Port",GetLastError());
			break;
        }
		
		index++;
		index%= sizeof(ptz_cmd)/7;
		Sleep(4000);
		
	}while(1);
	
	
     
end:
	CloseHandle(hComm);//Closing the Serial Port
	printf("\niap exit!\n");
	//_getch();
}//End of Main()

int com_rx(HANDLE hComm,unsigned char *rxbuf)
{
    //printf("\n\n    Waiting for Data Reception");
  BOOL Status;
  DWORD NoBytesRead;                     // Bytes read by ReadFile()
  DWORD dwEventMask;                     // Event mask to trigger
  char  TempChar;                        // Temperory Character
  int i = 0;

  
  Status = WaitCommEvent(hComm, &dwEventMask, NULL); //Wait for the character to be received
  	
  /*-------------------------- Program will Wait here till a Character is received ------------------------*/				

  if (Status == FALSE)
  {
    printf("\n    Error! in Setting WaitCommEvent()");
  }
  else //If  WaitCommEvent()==True Read the RXed data using ReadFile();
  {
    i = 0;
    //printf("\n\n    Characters Received");
    do
    {
      Status = ReadFile(hComm, &TempChar, sizeof(TempChar), &NoBytesRead, NULL);
      rxbuf[i] = TempChar;
      i++;
    }
    while (NoBytesRead > 0);
  }

  return i;
}

int com_tx(HANDLE hComm,unsigned char *txbuf, unsigned char txlen)
{
  BOOL Status;
  int ret = 0;
  
  Status = WriteFile(hComm,               // Handle to the Serialport
						   txbuf,            // Data to be written to the port 
						   txlen,   // No of bytes to write into the port
						   NULL,  // No of bytes written to the port
						   NULL);
		
  if (Status != TRUE)
    ret = -1;

  return ret;
}